package com.ax.framework.jfinal.server

import com.ax.asInstanceOf
import com.jfinal.server.undertow.CompositeResourceManager
import com.jfinal.server.undertow.UndertowConfig
import com.jfinal.server.undertow.UndertowServer
import com.jfinal.server.undertow.WebBuilder
import io.undertow.Handlers
import io.undertow.Handlers.websocket
import io.undertow.Undertow
import io.undertow.server.HttpHandler
import io.undertow.server.handlers.PathHandler
import io.undertow.server.handlers.SetHeaderHandler
import io.undertow.server.handlers.resource.ClassPathResourceManager
import io.undertow.websockets.core.*
import java.util.function.Consumer
import javax.servlet.ServletException


class AppUndertowServer(undertowConfig: UndertowConfig) : UndertowServer(undertowConfig) {
    override fun configHttp() {
        var httpHandler: HttpHandler? = null
        try {
            httpHandler = deploymentManager.start()
        } catch (e: ServletException) {
            stopSilently()
            throw RuntimeException(e)
        }

        var pathHandler: HttpHandler = Handlers.path().addPrefixPath(config.contextPath, httpHandler!!)

        configWebSocket(pathHandler.asInstanceOf());

        configHandler(pathHandler)
        configGzip(pathHandler)
        pathHandler = SetHeaderHandler(pathHandler, "Server", "Nginx")

        pathHandler = configSsl(pathHandler)

        builder
                .addHttpListener(config.port, config.host)
                // .setServerOption(UndertowOptions.ALWAYS_SET_KEEP_ALIVE, false)
                .setHandler(pathHandler)

        //.setHandler(ResourceHandler(ClassPathResourceManager(AppUndertowServer::class.java.classLoader)))

        //urlskiphandler处理之后, 会由DefaultServlet处理, 在它初始化时内部的resourceManager为JF的CompositeResourceManager, 
        deploymentInfo.resourceManager.asInstanceOf<CompositeResourceManager>().add(ClassPathResourceManager(AppUndertowServer::class.java.classLoader))


    }

    override fun configWeb(webBuilder: Consumer<WebBuilder>?): UndertowServer {
        return super.configWeb(webBuilder)
    }

    override fun init() {
        builder = Undertow.builder()

        configJFinalPathKit()
        configUndertow()

        // configListener();

        // configServlet();
        // configFilter();
        configWeb()

        configJFinalFilter()

    }

    private fun configWebSocket(handler: PathHandler) {
        handler.addPrefixPath("/ws", websocket { exchange, channel ->
            channel.receiveSetter.set(object : AbstractReceiveListener() {

                override fun onFullTextMessage(channel: WebSocketChannel?, message: BufferedTextMessage?) {
                    val messageData = message!!.data
                    for (session in channel!!.peerConnections) {
                        WebSockets.sendText(messageData, session, null)
                    }
                }

                override fun onBinary(webSocketChannel: WebSocketChannel, messageChannel: StreamSourceFrameChannel) {
                    super.onBinary(webSocketChannel, messageChannel)
                }

            })
            channel.resumeReceives()
        })
    }
}